// run: $exec < input
#include <cstdio>
#include <algorithm>
#include <utility>

int const maxn = 310000;
int end_point[2 * maxn], next[2 * maxn], head[maxn];
int alloc = 1;
int parent[maxn];
int diameter[maxn];
int n, m, q;

void init()
{
	for (int i = 1; i <= n; i++)
		parent[i] = i, diameter[i] = 0;
}

int get_parent(int x)
{
	return x == parent[x] ? x : parent[x] = get_parent(parent[x]);
}

void set_union(int x, int y)
{
	int tx = get_parent(x);
	int ty = get_parent(y);
	if (tx == ty) return;
	parent[tx] = ty;
	int lx = diameter[tx]; lx += lx & 1;
	int ly = diameter[ty]; ly += ly & 1;
	diameter[ty] = std::max((lx + ly) / 2 + 1,
			std::max(diameter[tx], diameter[ty]));
}

void add_edge(int x, int y)
{
	end_point[alloc] = y; next[alloc] = head[x]; head[x] = alloc++;
	end_point[alloc] = x; next[alloc] = head[y]; head[y] = alloc++;
}

bool vis[maxn];

std::pair<int, int> dfs(int u, int f)
{
	std::pair<int, int> ret{0, -1};
	for (int p = head[u]; p; p = next[p]) {
		int v = end_point[p];
		if (v == f) continue;
		auto tmp = dfs(v, u);
		if (tmp.second > ret.second) ret = tmp;
	}
	if (ret.second == -1) ret.first = u;
	ret.second += 1;
	return ret;
}

int main()
{
	std::scanf("%d %d %d", &n, &m, &q);
	init();
	for (int i = 0, x, y; i < m; i++) {
		std::scanf("%d %d", &x, &y);
		add_edge(x, y);
		parent[get_parent(x)] = get_parent(y);
	}

	for (int i = 1; i <= n; i++) {
		if (vis[get_parent(i)]) continue;
		auto p = dfs(i, -1);
		diameter[get_parent(i)] = dfs(p.first, -1).second;
		vis[get_parent(i)] = true;
	}

	for (int i = 0, op, x, y; i < q; i++) {
		std::scanf("%d", &op);
		if (op == 1) {
			std::scanf("%d", &x);
			std::printf("%d\n", diameter[get_parent(x)]);
		} else {
			std::scanf("%d %d", &x, &y);
			set_union(x, y);
		}
	}
}

